import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

public class PersonList {
    private HashMap<String, Person> personMap = new HashMap<String, Person>();
    private static Person personForFunc = new Person();

    public HashMap<String, Person> getPersonMap() {
        return personMap;
    }

    // 检查PID格式并输出错误，返回如果错误返回null，否则返回一个person对象
    public Person newPerson(String name, String sexString, String phoneNum, String PID, String type) {
        Person person = Person.newSudoPerson(name, sexString, phoneNum, type);
        if (person != null) {
            if (!person.checkPID(PID, type)) {
                System.out.println(type + " " + MyUtil.SUDO_PID_ERROR);
                person = null;
            } else if (personMap.containsKey(PID)) {
                System.out.println(type + " " + MyUtil.SUDO_PID_EXISTS);
                person = null;
            } else if (MyUtil.containPhone(personMap, person.getPhoneNum()) != null) {
                System.out.println("Phone number exists");
                person = null;
            } else {
                person.setPID(PID);
                personMap.put(PID, person);
                System.out.println("Add new " + type.toLowerCase() + " success");
            }
        }
        return person;
    }

    public void deletePerson(String PID, String type) {
        if (!personForFunc.checkPID(PID, type)) {
            System.out.println("D-" + type + " " + MyUtil.SUDO_PID_ERROR);
        } else if (!personMap.containsKey(PID)) {
            System.out.println("D-" + type + " PID doesn't exist");
        } else {
            personMap.remove(PID);
            System.out.println("Delete " + type.toLowerCase() + " success");
        }
    }

    public void printAll() {
        List<Person> all = new ArrayList<Person>();
        for (String PersonID : personMap.keySet()) {
            all.add(personMap.get(PersonID));
        }
        printPersonList(all, true);

    }

    public void printPersonList(List<Person> personList, boolean all) {
        if (personList.isEmpty()) {
            System.out.println(all ? MyUtil.SUDO_EMPTY : "no output");
        } else {
            Comparator cmp = new PersonComparator();
            Collections.sort(personList, cmp);
            MyUtil.printComparedPersonList(personList, 0, personList.size());
        }

    }

    public void loginByID(String PID, String PWD) {
        Person person;
        if (!personForFunc.checkPID(PID, "ALL")) {
            System.out.println(MyUtil.SUDO_PID_ERROR);
        } else if (!personMap.containsKey(PID)) {
            System.out.println("Pid not exist");
        } else {
            person = personMap.get(PID);
            if (PWD.equals(person.getPWD())) {
                System.out.println(MyUtil.SUDO_LOGIN_SUCCESS);
                LoginCommand.loginCommand(person);
            } else {
                System.out.println(MyUtil.SUDO_PWD_UNMATCHED);
            }
        }
    }

    public void loginByName(String name, String PWD) {
        Person person;
        if (!Person.checkName(name)) {
            System.out.println("Pname illegal");
        } else if (MyUtil.containName(personMap, name) == null) {
            System.out.println("Pname not exist");
        } else {
            person = MyUtil.containName(personMap, name);
            if (PWD.equals(person.getPWD())) {
                System.out.println(MyUtil.SUDO_LOGIN_SUCCESS);
                LoginCommand.loginCommand(person);
            } else {
                System.out.println(MyUtil.SUDO_PWD_UNMATCHED);
            }
        }
    }

}

class PersonComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        // TODO Auto-generated method stub
        if (p1 instanceof Customer && (p2 instanceof Waiter || p2 instanceof Cook)) {
            return -1;
        } else if (p1 instanceof Waiter && p2 instanceof Cook) {
            return -1;
        } else if (p1.getClass().equals(p2.getClass())) {
            return p1.getPID().compareTo(p2.getPID()) > 0 ? 1 : -1;
        } else {
            return 1;
        }
    }
}